const merge = require('webpack-merge')
const webpack = require('webpack')
const _ = require('lodash')
const { resolve } = require('../../helper')
const BaseModules = require('../BaseModules')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const { CommonLoaders } = require('../LoaderModules')



module.exports = new class {
	constructor(){
		this.externals = {}
		this.injectAssets = {
			injectJS: (BaseModules.command.dev || BaseModules.command.debug) ?
			['/vconsole'] : [],
			injectCSS: []
		}
		this.commonWebpackConf = this.createCommonWebpackConf()
	}

	createBundleStat(){
		const bundleList = BaseModules.createBundleList()

		return bundleList.reduce((pre, cur) => {
			
			const stat = cur.reduce((pre1, cur1) => {
				const { type, id, param } = cur1
				const { title, ...other } = param
				if(_.isEmpty(other) == false){
					pre1[`${id}`] = other
				}
				return pre1
			}, {})
			return merge(pre, stat)
		}, {})
	}

	createInjectAssets(value, key){
		const filename = BaseModules.transformOutputPath(value.output || key)
		this.injectAssets.injectJS.push(filename)
		if(value.css !== false){
			this.injectAssets.injectCSS.push(filename)
		}
	}

	createExternals(value, key){
		if(value.exports && value.exports.length > 0){
			value.exports.forEach(lib => this.externals[lib] = key + '("'+ lib + '")')
		}else{
			this.externals[key] = key + '()'
		}
		value.required && this.createInjectAssets(value, key)
	}

	createCommonWebpackConf(){

		const { plugins, ...other } = BaseModules.userBaseWebackConf
		return _.transform(BaseModules.commonConf, (result, value, key) => {
			const conf = Object.assign({}, other, {
				module:{ noParse: [/\.min\.js$/], rules: [...CommonLoaders()] },
				entry: {}, optimization:{},
				plugins: [
					...plugins,
					new ExtractTextPlugin({
						filename: '[name].css'
					}),
					new webpack.DefinePlugin({
						'bundleStat': JSON.stringify(this.createBundleStat()),
						'bundleId': JSON.stringify(BaseModules.appList)
					})
				],
				output: {
					path: BaseModules.command.dev ? resolve(BaseModules.appConf.output) : resolve(BaseModules.appConf.output, BaseModules.location.base),
					filename: '[name].js',
					publicPath: './',
					libraryExport: 'default',
					libraryTarget: 'umd',
					library: key
				}
			})
			conf.entry[value.output || key] = resolve(BaseModules.appConf.commonModules, key)
			this.createExternals(value, key)
			result.push(conf)
		}, [])
	}
}